using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Browser;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
using Lib.Approval;
using Lib.Helper;
using Lib.Mail;
using MSIACCSL2.ApplicationStateServices;
using MSIACCSL2.Command;
using MSIACCSL2.CostCenterServices;
using MSIACCSL2.CustomerServices;
using MSIACCSL2.DeliveryOrderServices;
using MSIACCSL2.DeliveryTypeServices;
using MSIACCSL2.InventoryServices;
using MSIACCSL2.ItemServices;
using MSIACCSL2.PalletServices;
using MSIACCSL2.SalesOrderServices;
using MSIACCSL2.SpkServices;
using MSIACCSL2.SubGroupServices;
using MSIACCSL2.Views.DeliveryOrder;
using MSIACCSL2.WarehouseServices;
using WcfService1.DTO;
using DeleteDetailCompletedEventArgs = MSIACCSL2.DeliveryOrderServices.DeleteDetailCompletedEventArgs;
using GetListByCriteriaCompletedEventArgs = MSIACCSL2.DeliveryOrderServices.GetListByCriteriaCompletedEventArgs;
using GetListCompletedEventArgs = MSIACCSL2.DeliveryOrderServices.GetListCompletedEventArgs;
using SaveCompletedEventArgs = MSIACCSL2.DeliveryOrderServices.SaveCompletedEventArgs;

namespace MSIACCSL2.ViewModels
{
    public class DeliveryOrderViewModel : ViewModelBase
    {
        #region Delegates

        public delegate void Completed(Object param);

        #endregion

        private static Search frmSearch;
        private static string OrderType;
        private static string PropertySort;
        public static Mode mode;
        public static Completed OnSearchCompleted;
        private static NavigationService _NavigationService;
        private readonly AplicationStateServicesClient ApplicationService;
        private readonly CostCenterServicesClient CostCenterClient;


        private readonly CustomerServicesClient CustomerClient;
        private readonly DeliveryTypeServicesClient DeliveryTypeClient;
        private readonly ItemServicesClient ItemClient;
        private readonly PalletServicesClient PalletClient;
        private readonly SalesOrderServicesClient SalesOrderClient;
        private readonly SubGroupServiceClient SubgroupClient;
        private readonly WarehouseServicesClient WarehouseClient;
        private readonly DeliveryOrderServicesClient client;
        private readonly SpkServicesClient spkClient;
        private readonly ValidationHandler validationHandler;
        private int CurrentPage;
        private InventoryServiceClient InventoryClient;
        private bool IsUsed;
        private ObservableCollection<int> Pages;
        private ObservableCollection<CostCenterDTO> _CostCenters;
        private ObservableCollection<CustomerDTO> _Customers;
        private DeliveryOrderDTO _DeliveryOrder;
        private PagedCollectionView _DeliveryOrders;
        private ObservableCollection<DeliveryTypeDTO> _DeliveryTypes;
        private string _Expression;
        private ObservableCollection<InventoryDTO> _Inventories;
        private bool _IsBusy;
        private bool _IsEnabled;
        private ObservableCollection<SalesOrderDTO> _SalesOrders;
        private ObservableCollection<SpkDTO> _Spks;
        private WarehouseDTO _WarehouseSelected;
        private List<string> _errors;
        private InventoryDTO _inventory;
        private ObservableCollection<ItemDTO> _items;
        private Visibility _messageVisibility;
        private PagedCollectionView _pageSources;
        private ObservableCollection<PalletDTO> _pallets;
        private string _serialNumber;
        private ObservableCollection<SubGroupDTO> _subgroups;
        private ObservableCollection<WarehouseDTO> _warehouses;
        private Dictionary<string, object> criteria;
        private string expression;
        private Visibility _gridDOVisibility;

        public DeliveryOrderViewModel()
        {
            WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
            IsEnabled = true;
            if (!DesignerProperties.IsInDesignTool)
            {
                client = new DeliveryOrderServicesClient();
                CustomerClient = new CustomerServicesClient();
                DeliveryTypeClient = new DeliveryTypeServicesClient();
                SalesOrderClient = new SalesOrderServicesClient();
                InventoryClient = new InventoryServiceClient();
                ItemClient = new ItemServicesClient();
                SubgroupClient = new SubGroupServiceClient();
                WarehouseClient = new WarehouseServicesClient();
                PalletClient = new PalletServicesClient();
                CostCenterClient = new CostCenterServicesClient();
                spkClient = new SpkServicesClient();
                Errors = new List<string>();
                ApplicationService = new AplicationStateServicesClient();

                OnPageChanged = new DelegateCommand(PageIndexChanged, CanPageIndexChanged);
                Save = new DelegateCommand(SaveDeliveryOrder, CanSave);
                New = new DelegateCommand(NewDeliveryOrder, CanNew);
                Unload = new DelegateCommand(Release, CanUnload);
                SearchCommand = new DelegateCommand(SearchDeliveryOrder, CanSearch);
                SearchResultCommand = new DelegateCommand(SearchResult, CanSearchResult);
                CancelCommand = new DelegateCommand(Cancel, CanCancelCommand);
                validationHandler = new ValidationHandler();
                MessageVisibility = Visibility.Collapsed;
                LoadSOCommand = new DelegateCommand(LoadSalesOrder, CanLoadSOCommand);
                LoadSPKCommand = new DelegateCommand(LoadSPK, CanLoadSPK);
                gridDOVisibility = Visibility.Collapsed;

                if (mode == Mode.Edit)
                {
                    PrepareEdit();
                }
                else if (mode == Mode.Search)
                {
                    DeliveryOrder = new DeliveryOrderDTO();
                    DeliveryOrder.DODate = null;
                    GetDeliveryTypeList();
                }
                else if (mode == Mode.Add)
                {
                    PrepareAdd();
                }
                else
                {
                    GetList(1, null);
                }
            }
        }


        public ObservableCollection<CostCenterDTO> CostCenters
        {
            get { return _CostCenters; }
            private set
            {
                if (CostCenters == value) return;
                _CostCenters = value;
                FirePropertyChanged("CostCenters");
            }
        }

        public PagedCollectionView DeliveryOrders
        {
            get { return _DeliveryOrders; }

            private set
            {
                if (DeliveryOrders == value) return;
                _DeliveryOrders = value;
                int i = (CurrentPage*30);
                foreach (object DeliveryOrder in DeliveryOrders)
                {
                    i += 1;

                    ((DeliveryOrderDTO) DeliveryOrder).No = i;
                }
                FirePropertyChanged("DeliveryOrders");
                DeliveryOrders.CollectionChanged += DeliveryOrder_CollectionChanged;
            }
        }

        public PagedCollectionView PageSources
        {
            get { return _pageSources; }
            private set
            {
                if (PageSources == value) return;
                _pageSources = value;
                FirePropertyChanged("PageSources");
            }
        }


        public ObservableCollection<CustomerDTO> Customers
        {
            get { return _Customers; }
            private set
            {
                if (Customers == value) return;
                _Customers = value;
                FirePropertyChanged("Customers");
            }
        }


        public ObservableCollection<DeliveryTypeDTO> DeliveryTypes
        {
            get { return _DeliveryTypes; }
            private set
            {
                if (DeliveryTypes == value) return;
                _DeliveryTypes = value;
                FirePropertyChanged("DeliveryTypes");
            }
        }


        public ObservableCollection<SalesOrderDTO> SalesOrders
        {
            get { return _SalesOrders; }
            internal set
            {
                if (SalesOrders == value) return;
                _SalesOrders = value;
                FirePropertyChanged("SalesOrders");
            }
        }

        public ObservableCollection<SpkDTO> Spks
        {
            get { return _Spks; }
            private set
            {
                if (Spks == value) return;
                _Spks = value;
                FirePropertyChanged("Spks");
            }
        }

        public ObservableCollection<InventoryDTO> InventorySearchs
        {
            get { return _Inventories; }
            private set
            {
                if (InventorySearchs == value) return;
                _Inventories = value;
                FirePropertyChanged("InventorySearchs");
            }
        }

        public String SerialNumber
        {
            get { return _serialNumber; }
            set
            {
                if (SerialNumber == value) return;
                _serialNumber = value;
                FirePropertyChanged("SerialNumber");
            }
        }


        public bool IsBusy
        {
            get { return _IsBusy; }
            internal set
            {
                _IsBusy = value;
                FirePropertyChanged("IsBusy");
            }
        }

        public ObservableCollection<ItemDTO> Items
        {
            get { return _items; }
            private set
            {
                if (Items == value) return;
                _items = value;
                FirePropertyChanged("Items");
            }
        }

        public ObservableCollection<WarehouseDTO> Warehouses
        {
            get { return _warehouses; }
            private set
            {
                if (Warehouses == value) return;
                _warehouses = value;
                FirePropertyChanged("Warehouses");
            }
        }


        public ObservableCollection<PalletDTO> Pallets
        {
            get { return _pallets; }
            private set
            {
                if (Pallets == value) return;
                _pallets = value;
                FirePropertyChanged("Pallets");
            }
        }

        public ObservableCollection<SubGroupDTO> Subgroups
        {
            get { return _subgroups; }
            private set
            {
                if (Subgroups == value) return;
                _subgroups = value;
                FirePropertyChanged("Subgroups");
            }
        }

        public WarehouseDTO WarehouseSelected
        {
            get { return _WarehouseSelected; }
            set
            {
                if (WarehouseSelected == value) return;
                _WarehouseSelected = value;
                FirePropertyChanged("WarehouseSelected");
            }
        }
    
        public long RecordCount { get; set; }

        //Buat binding ke child form waktu mau edit
        public DeliveryOrderDTO DeliveryOrder
        {
            get { return _DeliveryOrder; }
            private set
            {
                if (DeliveryOrder == value) return;
                _DeliveryOrder = value;
                FirePropertyChanged("DeliveryOrder");
            }
        }


        public ICommand OnPageChanged { get; set; }
        public ICommand Save { get; set; }
        public ICommand New { get; set; }
        public ICommand Edit { get; set; }
        public ICommand Unload { get; set; }
        public ICommand SearchCommand { get; set; }
        public ICommand SearchResultCommand { get; set; }
        public ICommand CancelCommand { get; set; }

        public List<string> Errors
        {
            get { return _errors; }
            private set
            {
                if (Errors == value) return;
                _errors = value;
                FirePropertyChanged("Errors");
            }
        }

        public Visibility MessageVisibility
        {
            get { return _messageVisibility; }
            private set
            {
                if (MessageVisibility == value) return;
                _messageVisibility = value;
                FirePropertyChanged("MessageVisibility");
            }
        }

        public Visibility gridDOVisibility
        {
            get { return _gridDOVisibility; }
            internal set
            {
                if (gridDOVisibility == value) return;
                _gridDOVisibility = value;
                FirePropertyChanged("gridDOVisibility");
            }
        }

        public string Expression
        {
            get { return _Expression; }
            set
            {
                if (Expression == value) return;
                _Expression = value;
                FirePropertyChanged("Expression");
            }
        }

        public bool IsEnabled
        {
            get { return _IsEnabled; }
            internal set
            {
                _IsEnabled = value;
                FirePropertyChanged("IsEnabled");
            }
        }

        public ICommand LoadSOCommand { get; set; }

        public ICommand LoadSPKCommand { get; set; }

        public InventoryDTO Inventory
        {
            get { return _inventory; }
            internal set
            {
                _inventory = value;
                FirePropertyChanged("Inventory");
            }
        }

        private void PrepareEdit()
        {
            DeliveryOrder = (DeliveryOrderDTO) Navigation.Args;
            GetDeliveryOrder(DeliveryOrder.DONo);
            CekTransaksi();
        }


        private void PrepareAdd()
        {
            GetDeliveryTypeList();
            GetCostCenterList();
            GetWarehouseList(Mode.Add);
            DeliveryOrder = new DeliveryOrderDTO();
            DeliveryOrder.DeliveryOrderDetails = new ObservableCollection<DeliveryOrderDetailDTO>();
            GetSPKList(Mode.Add);
            //CekTransaksi();
        }


        private void GetDeliveryOrder(string DONo)
        {
            IsBusy = true;
            client.GetDeliveryOrderCompleted += client_GetDeliveryOrderCompleted;
            client.GetDeliveryOrderAsync(DONo);
        }

        private void client_GetDeliveryOrderCompleted(object sender, GetDeliveryOrderCompletedEventArgs e)
        {
            client.GetDeliveryOrderCompleted += client_GetDeliveryOrderCompleted;
            DeliveryOrder = e.Result;

            if (DeliveryOrder.Status == Status.Void || DeliveryOrder.Status == Status.Close) IsEnabled = false;
           

            if (DeliveryOrder.DeliveryOrderDetails == null)
                DeliveryOrder.DeliveryOrderDetails = new ObservableCollection<DeliveryOrderDetailDTO>();
            if (DeliveryOrder.DeliveryOrderDetails.Count == 0)
                DeliveryOrder.DeliveryOrderDetails.Add(new DeliveryOrderDetailDTO());

            GetWarehouseList(Mode.Edit);
            GetDeliveryTypeList();
            GetCostCenterList();
            //GetSalesOrderList(DeliveryOrder.CostCenter);
            GetSPKList(Mode.Edit);
            IsBusy = false;
        }

        private void GetWarehouseList(Mode mode)
        {
            WarehouseClient.GetAllWarehouseCompleted += WarehouseClient_GetAllWarehouseCompleted;
            WarehouseClient.GetAllWarehouseAsync(mode);
        }

        private void WarehouseClient_GetAllWarehouseCompleted(object sender, GetAllWarehouseCompletedEventArgs e)
        {
            WarehouseClient.GetAllWarehouseCompleted -= WarehouseClient_GetAllWarehouseCompleted;
            Warehouses = e.Result;
            var mode = (Mode) e.UserState;
            if (mode == Mode.Edit)
            {
                if (DeliveryOrder.Warehouse != null)
                    DeliveryOrder.Warehouse =
                        Warehouses.FirstOrDefault(x => x.KodeWarehouse == DeliveryOrder.Warehouse.KodeWarehouse);
            }
        }

        private void GetCostCenterList()
        {
            CostCenterClient.GetAllCostCenterCompleted += CostCenterClient_GetAllCostCenterCompleted;
            CostCenterClient.GetAllCostCenterAsync();
        }

        private void CostCenterClient_GetAllCostCenterCompleted(object sender, GetAllCostCenterCompletedEventArgs e)
        {
            CostCenterClient.GetAllCostCenterCompleted -= CostCenterClient_GetAllCostCenterCompleted;
            CostCenters = e.Result;
            if (DeliveryOrder != null)
                if (DeliveryOrder.CostCenter != null)
                    DeliveryOrder.CostCenter =
                        CostCenters.FirstOrDefault(x => x.CostCenterId == DeliveryOrder.CostCenter.CostCenterId);
        }


        public void GetSPKList(Mode mode)
        {
            spkClient.GetAllSpkCompleted += spkClient_GetAllSpkCompleted;
            spkClient.GetAllSpkAsync(mode);
        }

        private void spkClient_GetAllSpkCompleted(object sender, GetAllSpkCompletedEventArgs e)
        {
            spkClient.GetAllSpkCompleted -= spkClient_GetAllSpkCompleted;
            Spks = e.Result;
            Spks.Add(DeliveryOrder.Spk);
            var Mode = (Mode) e.UserState;
            if (Mode == Mode.Edit)
            {
                if (DeliveryOrder.Spk != null)
                    DeliveryOrder.Spk = Spks.FirstOrDefault(x => x.NoSPK == DeliveryOrder.Spk.NoSPK);
            }
        }

        public bool CanLoadSPK(Object param)
        {
            return true;
        }

        public void Complete(Object param)
        {
            OnSearchCompleted(param);
        }

        private void DeliveryOrder_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (((PagedCollectionView) sender).SortDescriptions.Count > 0)
            {
                if (((PagedCollectionView) sender).SortDescriptions[0].PropertyName.ToLower() == "no") return;

                PropertySort = ((PagedCollectionView) sender).SortDescriptions[0].PropertyName;
                if (string.IsNullOrEmpty(OrderType))
                {
                    OrderType = "ASC";
                }
                else
                {
                    OrderType = OrderType == "ASC" ? OrderType = "DESC" : OrderType = "ASC";
                }
                GetList(1, PropertySort);
            }
        }


        public void SaveDeliveryOrder(Object deliveryOrder)
        {
            //DeliveryOrder = (DeliveryOrderDTO) deliveryOrder;
            if (DeliveryOrder.DeliveryOrderDetails.Count == 1)
            {
                //Bila tidak ada yang dipilih di detail maka details harus dihapus
                if (DeliveryOrder.DeliveryOrderDetails[0].Inventory == null)
                    DeliveryOrder.DeliveryOrderDetails.Clear();
            }
            Validate();
            if (Errors.Count > 0) return;
            DeliveryOrder.created_by = GlobalVar.User.UserID;
            DeliveryOrder.modified_by = GlobalVar.User.UserID;
            IsBusy = true;
            client.SaveCompleted += client_SaveCompleted;
            client.SaveAsync(DeliveryOrder, mode);
        }

        private void client_SaveCompleted(object sender, SaveCompletedEventArgs e)
        {
            client.SaveCompleted -= client_SaveCompleted;
            IsBusy = false;

            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
                return;
            }
           
            mode = (Mode) e.UserState;
            if (e.Result)
            {
                ClearTransaksi(mode);
                mode = Mode.Idle;
                Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/Index", UriKind.Relative));
            }       
            else
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
            }
        }


        public void GetList(int? page, string sortProp)
        {
            IsBusy = true;
            client.GetListCompleted += client_GetListCompleted;
            client.GetListAsync(page ?? 1, sortProp, OrderType);
        }

        private void client_GetListCompleted(object sender, GetListCompletedEventArgs e)
        {
            RecordCount = e.recordCount;
            if (PageSources == null) CreatePageNumber();
            client.GetListCompleted -= client_GetListCompleted;
            DeliveryOrders = new PagedCollectionView(e.Result);
            IsBusy = false;
            Complete(this);
        }


        private void NewDeliveryOrder(Object param)
        {
            mode = Mode.Add;
            Navigation.MyNavigation = (NavigationService) param;
            Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/frmAdd", UriKind.Relative));
        }


        private void SearchDeliveryOrder(Object param)
        {
            mode = Mode.Search;
            frmSearch = new Search();
            frmSearch.Show();
        }


        private void SearchResult(Object param)
        {
            criteria = new Dictionary<string, object>();

            foreach (PropertyInfo prop in DeliveryOrder.GetType().GetProperties())
            {
                if (prop.PropertyType == typeof (Decimal))
                {
                    if ((Decimal) prop.GetValue(DeliveryOrder, null) == 0) continue;
                }
                if (prop.PropertyType == typeof (Int32))
                {
                    if ((Int32) prop.GetValue(DeliveryOrder, null) == 0) continue;
                }
                if (prop.PropertyType == typeof (Int64))
                {
                    if ((Int64) prop.GetValue(DeliveryOrder, null) == 0) continue;
                }
                if (prop.PropertyType == typeof (Double))
                {
                    if ((Double) prop.GetValue(DeliveryOrder, null) == 0) continue;
                }
                if (prop.PropertyType == typeof (String))
                {
                    if (String.IsNullOrEmpty((String) prop.GetValue(DeliveryOrder, null))) continue;
                }
                if (prop.PropertyType == typeof (DateTime))
                {
                    if (prop.GetValue(DeliveryOrder, null).ToString().Contains("0001")) continue;
                }
                if (prop.GetValue(DeliveryOrder, null) == null) continue;
                if (prop.PropertyType.Name == "No") continue;

                if (prop.PropertyType.Name.ToLower().Contains("dto"))
                {
                    foreach (PropertyInfo propertyInfo in prop.GetValue(DeliveryOrder, null).GetType().GetProperties()
                        )
                    {
                        if (propertyInfo.Name.ToLower().Contains("id") || propertyInfo.Name.ToLower().Contains("kode") ||
                            propertyInfo.Name.ToLower().Contains("serial") ||
                            propertyInfo.Name.ToLower().Contains("code"))
                        {
                            criteria.Add(prop.Name, propertyInfo.GetValue(prop.GetValue(DeliveryOrder, null), null));
                            break;
                        }
                    }
                }
                else
                {
                    criteria.Add(prop.Name, prop.GetValue(DeliveryOrder, null));
                }
            }

            expression = string.Empty;
            if (frmSearch.rblOr.IsChecked ?? false) expression = "OR";
            else expression = "AND";
            DeliveryOrderSearch(criteria, expression,1);
        }

        private void DeliveryOrderSearch(Dictionary<String, Object> criteria, string expression,int page)
        {
            if (criteria.ContainsKey("Status")) criteria.Remove("Status");
            frmSearch.DialogResult = true;
            IsBusy = true;
            Complete(this);
            client.GetListByCriteriaCompleted += client_GetListByCriteriaCompleted;
            client.GetListByCriteriaAsync(criteria, expression, page);
        }

        private void client_GetListByCriteriaCompleted(object sender, GetListByCriteriaCompletedEventArgs e)
        {
            client.GetListByCriteriaCompleted -= client_GetListByCriteriaCompleted;
            DeliveryOrders = new PagedCollectionView(e.Result);
            if (RecordCount != e.recordCount)
            {
                RecordCount = e.recordCount;
                CreatePageNumber();
            }
            IsBusy = false;
        }


        private void GetDeliveryTypeList()
        {
            DeliveryTypeClient.GetAllDeliveryTypeCompleted += DeliveryTypeClient_GetAllDeliveryTypeCompleted;
            DeliveryTypeClient.GetAllDeliveryTypeAsync();
        }

        private void DeliveryTypeClient_GetAllDeliveryTypeCompleted(object sender,
                                                                    GetAllDeliveryTypeCompletedEventArgs e)
        {
            DeliveryTypeClient.GetAllDeliveryTypeCompleted -= DeliveryTypeClient_GetAllDeliveryTypeCompleted;
            DeliveryTypes = e.Result;

            if (DeliveryOrder != null)
            {
                if (DeliveryOrder.DeliveryType == null) return;
                DeliveryOrder.DeliveryType =
                    DeliveryTypes.FirstOrDefault(s => s.DeliveryCode == DeliveryOrder.DeliveryType.DeliveryCode);
            }
        }

        public void GetSalesOrderList(Object param)
        {
            if (param == null) return;
            SalesOrderClient.GetSalesOrderListByCostCenterCompleted +=
                SalesOrderClient_GetSalesOrderListByCostCenterCompleted;
            SalesOrderClient.GetSalesOrderListByCostCenterAsync(param as CostCenterDTO);
        }

        private void SalesOrderClient_GetSalesOrderListByCostCenterCompleted(object sender,
                                                                             GetSalesOrderListByCostCenterCompletedEventArgs
                                                                                 e)
        {
            SalesOrderClient.GetSalesOrderListByCostCenterCompleted -=
                SalesOrderClient_GetSalesOrderListByCostCenterCompleted;
            SalesOrders = e.Result;
              
            //Edit Mode
            if (DeliveryOrder != null)
            {
                SalesOrders = new ObservableCollection<SalesOrderDTO>(SalesOrders.Where(x => x.SODate <= DeliveryOrder.DODate));
                if (DeliveryOrder.SalesOrder == null) return;
                if (! SalesOrders.Any(x=>x.SONo == DeliveryOrder.SalesOrder.SONo))
                    SalesOrders.Add(DeliveryOrder.SalesOrder);
                DeliveryOrder.RaisePropertyChanged("SalesOrder");
            }
        }


        private void CreatePageNumber()
        {
            Pages = new ObservableCollection<int>();
            for (int i = 0; i < RecordCount; i++)
            {
                Pages.Add(i);
            }
            PageSources = new PagedCollectionView(Pages);
        }


        private void PageIndexChanged(Object pageIndex)
        {
            //Jika Pertama kali jangan di Getlagi
            DeliveryOrder = null;
            if (DeliveryOrders != null && CurrentPage != (int) pageIndex)
            {
                CurrentPage = (int) pageIndex;
                if (mode == Mode.Search)
                    DeliveryOrderSearch(criteria, expression, (int)pageIndex + 1);
                else if (String.IsNullOrEmpty(PropertySort))
                    GetList((int)pageIndex + 1, null);
                else GetList((int) pageIndex + 1, PropertySort);
            }
        }


        public bool CanPageIndexChanged(Object param)
        {
            return true;
        }


        public bool CanSave(Object param)
        {
            return true;
        }


        public bool CanNew(Object param)
        {
            return true;
        }

        public bool CanEdit(Object param)
        {
            return true;
        }


        public bool CanUnload(Object param)
        {
            return true;
        }


        public bool CanSearch(Object param)
        {
            return true;
        }

        public bool CanSearchResult(Object param)
        {
            return true;
        }

        public bool CanCancelCommand(Object param)
        {
            return true;
        }


        public void Release(Object param)
        {
            param = null;
            DeliveryOrder = null;
            OrderType = null;
            PropertySort = null;
            mode = Mode.Idle;
        }


        public void Refresh()
        {
            if (DeliveryOrders == null)
                GetList(1, null);
            else
                Complete(this);
        }


        public void Validate(string error = null)
        {
            Errors = new List<string>();

            //if (string.IsNullOrEmpty(DeliveryOrder.DONo))
            //    Errors.Add("Nomor DO tidak boleh kosong");
            if (DeliveryOrder.CostCenter == null)
                Errors.Add("CostCenter tidak boleh kosong!");
            //if (DeliveryOrder.SalesOrder == null && DeliveryOrder.Spk == null)
            //    Errors.Add("SPK atau SO tidak boleh kosong!");
            if (DeliveryOrder.Warehouse == null)
                Errors.Add("Warehouse tidak boleh kosong!");
            if (DeliveryOrder.DeliveryOrderDetails.Count < 1)
                Errors.Add("DeliveryOrder Detail harus diisi!");

            if (!string.IsNullOrEmpty(error))
                Errors.Add(error);

            if (Errors.Count > 0)
            {
                MessageVisibility = Visibility.Visible;
            }
            else
            {
                MessageVisibility = Visibility.Collapsed;
            }
        }

        public void Cancel(Object param)
        {
            MessageBoxResult res = MessageBox.Show("Are You Sure Want to Cancel ?", "Confirmation",
                                                   MessageBoxButton.OKCancel);
            if (res == MessageBoxResult.OK)
            {
                if (!IsUsed) ClearTransaksi(mode);
                mode = Mode.Idle;
                Navigation.MyNavigation.GoBack();
            }
        }

        public void GetLastNoDeliveryOrder(Object param)
        {
            if (param == null) return;
            client.GetLastDONoCompleted += client_GetLastNoDeliveryOrderCompleted;
            client.GetLastDONoAsync(param as CostCenterDTO, (param as CostCenterDTO).CostCenterId);
        }

        private void client_GetLastNoDeliveryOrderCompleted(object sender, GetLastDONoCompletedEventArgs e)
        {
            client.GetLastDONoCompleted -= client_GetLastNoDeliveryOrderCompleted;
            string res = e.Result;
            string formatSO = "0000";
            string kodeSO;
            if (e.Result.Length <= 4)
            {
                res = formatSO;
                kodeSO = e.Result;
            }
            else
            {
                res = e.Result.Split(new[] {"/"}, StringSplitOptions.RemoveEmptyEntries)[3];
                kodeSO = e.Result.Split(new[] {"/"}, StringSplitOptions.RemoveEmptyEntries)[0];
            }
            string soNum = formatSO.Substring(0, formatSO.Length - (int.Parse(res) + 1).ToString().Length) +
                           (int.Parse(res) + 1);

            string costCenter = e.UserState.ToString();
            DeliveryOrder.DONo = kodeSO + "/" + costCenter + "/" + DateTime.Now.Year + "/" + soNum;
        }


        public bool CanLoadSOCommand(Object param)
        {
            return true;
        }

        public void LoadSalesOrder(Object param)
        {
            if (param == null || param.GetType() == typeof(ComboBoxItem)) return;
            var SO = (SalesOrderDTO) param;
            SalesOrderClient.GetSalesOrderCompleted += SalesOrderClient_GetSalesOrderCompleted;
            SalesOrderClient.GetSalesOrderAsync(SO.SONo);
        }

        private void SalesOrderClient_GetSalesOrderCompleted(object sender, GetSalesOrderCompletedEventArgs e)
        {
            SalesOrderClient.GetSalesOrderCompleted -= SalesOrderClient_GetSalesOrderCompleted;
            DeliveryOrder.SalesOrder = e.Result;

            if (e.Result.DeliveryType != null)
                foreach (DeliveryTypeDTO dt in DeliveryTypes.Where(d => d.DeliveryCode == e.Result.DeliveryType.DeliveryCode))
                    DeliveryOrder.DeliveryType = dt;
            DeliveryOrder.DeliveryAddress = e.Result.DeliveryAddress;
            DeliveryOrder.CustomerName = e.Result.CustomerName;
            DeliveryOrder.Address = e.Result.Address;
            DeliveryOrder.Telp = e.Result.Telp;
            if (e.Result.Warehouse != null)
                DeliveryOrder.Warehouse =
                    Warehouses.FirstOrDefault(x => x.KodeWarehouse == e.Result.Warehouse.KodeWarehouse);

            //Tarik detailnya jika SOnya pake SerialNumber
            DeliveryOrder.DeliveryOrderDetails.Clear();
            if (e.Result.Type == "Inventory")
            {
                foreach (SalesOrderDetailDTO sod in e.Result.SalesOrderDetails)
                {
                    var dod = new DeliveryOrderDetailDTO
                                  {
                                      Inventory =
                                          sod.Inventory ,
                                      QtyPack = sod.Inventory != null ? sod.Inventory.QtyPack : 1,
                                      QtyUnit = sod.Qty,
                                      Panjang = sod.Panjang,
                                      Lebar = sod.Lebar,
                                      Tinggi = sod.Tinggi,
                                  };

                    if (dod.Inventory != null) dod.Inventory.GetQtyOnHand(DeliveryOrder.Warehouse.KodeWarehouse);
                    DeliveryOrder.DeliveryOrderDetails.Add(dod);
                }
            }

        }

        private void LoadSPK(Object param)
        {
            if (param == null) return;
            spkClient.GetSpkCompleted += spkClient_GetSpkCompleted;
            spkClient.GetSpkAsync(DeliveryOrder.Spk.NoSPK);
        }

        private void spkClient_GetSpkCompleted(object sender, GetSpkCompletedEventArgs e)
        {
            spkClient.GetSpkCompleted -= spkClient_GetSpkCompleted;
            DeliveryOrder.Spk = e.Result;

            if (e.Result.DeliveryType != null)
                foreach (
                    DeliveryTypeDTO dt in DeliveryTypes.Where(d => d.DeliveryCode == e.Result.DeliveryType.DeliveryCode)
                    )
                    DeliveryOrder.DeliveryType = dt;
            DeliveryOrder.DeliveryAddress = e.Result.DeliveryAddress;
            DeliveryOrder.CustomerName = e.Result.CustomerName;
            DeliveryOrder.Address = e.Result.Address;
            DeliveryOrder.Telp = e.Result.Telp;

            if (e.Result.Warehouse != null)
                DeliveryOrder.Warehouse =
                    Warehouses.FirstOrDefault(x => x.KodeWarehouse == e.Result.Warehouse.KodeWarehouse);

            //Tarik detailnya jika SOnya pake SerialNumber
            DeliveryOrder.DeliveryOrderDetails.Clear();
            if (e.Result.Type == "Inventory")
            {
                foreach (SpkDetailDTO sod in e.Result.SpkDetails)
                {
                    if (sod.Inventory != null)
                    {
                        var dod = new DeliveryOrderDetailDTO
                                      {
                                          Inventory =
                                              sod.Inventory,
                                          QtyPack = sod.Inventory.QtyPack,
                                          QtyUnit = sod.Qty,
                                          Panjang = sod.Panjang,
                                          Lebar = sod.Lebar,
                                          Tinggi = sod.Tinggi,
                                          Warehouses = Warehouses
                                      };

                        DeliveryOrder.DeliveryOrderDetails.Add(dod);
                    }
                }
            }


            IsBusy = false;
        }


        public void LoadDetailFromFile(Object param)
        {
            ImportHelper importHelper = new ImportHelper();
            IEnumerable<List<dynamic>> sourcesOld;
            importHelper.BrowseExcelFile(out sourcesOld);
            var sources = importHelper.LoadExcellFile(importHelper.listSheetNames.FirstOrDefault());
            

            ObservableCollection<InventoryDTO> inventoryDtos = new ObservableCollection<InventoryDTO>();
            if (sourcesOld == null || sourcesOld.Count() == 0)
            {
                if (sources != null)
                    foreach (dynamic data in sources)
                    {
                        string noLog = data.A;
                        if (string.IsNullOrEmpty(noLog)) continue;
                        inventoryDtos.Add(new InventoryDTO() { SerialNumber = noLog });
                    }

            }
            else
            {
                int i = 0;
                foreach (var data in sourcesOld)
                {
                    if (i > 0)
                    {
                        string noLog = data[0];
                        if (string.IsNullOrEmpty(noLog)) continue;
                        inventoryDtos.Add(new InventoryDTO() { SerialNumber = noLog });
                    }
                    i++;
                }
            }


            if (inventoryDtos.Count > 0)
            {
                GetInventoryList(inventoryDtos);
            }
        }

         public void GetInventoryList(ObservableCollection<InventoryDTO> inventoryDtos)
        {
        
            if (DeliveryOrder.Warehouse == null)
            {
                MessageBox.Show("Warehouse dipilih dulu!");
                return;
            }
            InventoryClient.GetInventoryListbyWarehouseCompleted += new EventHandler<GetInventoryListbyWarehouseCompletedEventArgs>(InventoryClient_GetInventoryListbyWarehouseCompleted);
            InventoryClient.GetInventoryListbyWarehouseAsync(inventoryDtos,DeliveryOrder.Warehouse.KodeWarehouse);
            IsBusy = true;
        }

        void InventoryClient_GetInventoryListbyWarehouseCompleted(object sender, GetInventoryListbyWarehouseCompletedEventArgs e)
        {
            InventoryClient.GetInventoryListbyWarehouseCompleted -= new EventHandler<GetInventoryListbyWarehouseCompletedEventArgs>(InventoryClient_GetInventoryListbyWarehouseCompleted);

            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
                return;
            }

            foreach (var InventoryTemp in e.Result)
            {
                var doDetail = new DeliveryOrderDetailDTO();
                if (doDetail != null && InventoryTemp != null)
                {
                    doDetail.Inventory = InventoryTemp;
                    doDetail.Panjang = InventoryTemp.Panjang;
                    doDetail.Lebar = InventoryTemp.Lebar;
                    doDetail.Tinggi = InventoryTemp.Warehouses.FirstOrDefault().Sheet;
                    doDetail.QtyUnit = InventoryTemp.Warehouses.FirstOrDefault().Qty;
                    doDetail.QtyUnit = doDetail.Inventory.Item.IsRounded
                                             ? doDetail.QtyUnit.Round(2, MidpointRounding.AwayFromZero)
                                             : doDetail.QtyUnit.Round(4, MidpointRounding.AwayFromZero);
                    doDetail.Inventory.GetQtyOnHand(DeliveryOrder.Warehouse.KodeWarehouse);
                    DeliveryOrder.DeliveryOrderDetails.Add(doDetail);
                   
                }
            }

            IsBusy = false;
        }



        //Untuk Detailnya atau Packing List
        public void Print(Object param)
        {
            Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/PrintPreviewDO", UriKind.Relative));
            Navigation.Args = param;
        }


        //Summarynya saja
        public void PrintSuratJalan(Object param)
        {
            Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/PrintPreviewSJ", UriKind.Relative));
            Navigation.Args = param;
        }

        public void SendEmail(Object param)
        {
            ChooseDestination chooseDestination = new ChooseDestination();
            chooseDestination.Show();
            EventAggregator.RegisterMessage("SendDestination", (x) =>
            {
                IsBusy = true;
                client.SendEmailCompleted += client_SendEmailCompleted;
                client.SendEmailAsync(param as DeliveryOrderDTO, (x as WarehouseDTO).EmailFolder);
            });

        }

        private void client_SendEmailCompleted(object sender, DeliveryOrderServices.SendEmailCompletedEventArgs e)
        {
            IsBusy = false;
            client.SendEmailCompleted -= client_SendEmailCompleted;
            if (e.Result) MessageBox.Show("Pengiriman Selesai");
        }

        public void GetItemList(Object param)
        {
            ItemClient.GetItemByNameCompleted += ItemClient_GetItemByNameCompleted;
            ItemClient.GetItemByNameAsync(param.ToString());
        }

        private void ItemClient_GetItemByNameCompleted(object sender, GetItemByNameCompletedEventArgs e)
        {
            ItemClient.GetItemByNameCompleted -= ItemClient_GetItemByNameCompleted;
            Items = e.Result;
        }

        public void GetSubGrouplist(Object param)
        {
            SubgroupClient.GetSubGroupListByNameCompleted += SubgroupClient_GetSubGroupListByNameCompleted;
            SubgroupClient.GetSubGroupListByNameAsync(param.ToString());
        }

        private void SubgroupClient_GetSubGroupListByNameCompleted(object sender,
                                                                   GetSubGroupListByNameCompletedEventArgs e)
        {
            SubgroupClient.GetSubGroupListByNameCompleted -= SubgroupClient_GetSubGroupListByNameCompleted;
            Subgroups = e.Result;
        }

        public void GetPalletList(Object param)
        {
            PalletClient.GetPalletByWarehouseCompleted += PalletClient_GetPalletByWarehouseCompleted;
            PalletClient.GetPalletByWarehouseAsync(param as WarehouseDTO);
        }

        private void PalletClient_GetPalletByWarehouseCompleted(object sender, GetPalletByWarehouseCompletedEventArgs e)
        {
            PalletClient.GetPalletByWarehouseCompleted -= PalletClient_GetPalletByWarehouseCompleted;
            Pallets = e.Result;
        }

        public void CekTransaksi()
        {
            ApplicationService.IsTransactionUsedCompleted += ApplicationService_IsTransactionUsedCompleted;
            if (string.IsNullOrEmpty(DeliveryOrder.DONo))
            {
                ApplicationService.IsTransactionUsedAsync(DeliveryOrder.ToString(), GlobalVar.User, mode);
                GlobalVar.CurrentTransaction = DeliveryOrder.ToString();
            }
            else
            {
                ApplicationService.IsTransactionUsedAsync(DeliveryOrder.DONo, GlobalVar.User, mode);
                GlobalVar.CurrentTransaction = DeliveryOrder.DONo;
            }
        }

        private void ApplicationService_IsTransactionUsedCompleted(object sender, IsTransactionUsedCompletedEventArgs e)
        {
            ApplicationService.IsTransactionUsedCompleted -= ApplicationService_IsTransactionUsedCompleted;
            IsUsed = e.Result;
            mode = (Mode) e.UserState;
            if (IsUsed)
            {
                MessageBox.Show("Transaksi sedang digunakan!");
                if (mode == Mode.Add) //If Add Mode
                {
                    mode = Mode.Idle;
                    Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/Index", UriKind.Relative));
                }
                else //Edit Mode just view Only
                {
                    IsEnabled = false;
                }
            }
        }

        private void ClearTransaksi(Mode mode)
        {
            ApplicationService.ClearTransactionCompleted += ApplicationService_ClearTransactionCompleted;
            if (mode == Mode.Add)
                ApplicationService.ClearTransactionAsync(DeliveryOrder.ToString(), GlobalVar.User);
            else
                ApplicationService.ClearTransactionAsync(DeliveryOrder.DONo, GlobalVar.User);
        }

        private void ApplicationService_ClearTransactionCompleted(object sender, AsyncCompletedEventArgs e)
        {
            ApplicationService.ClearTransactionCompleted -= ApplicationService_ClearTransactionCompleted;
        }

        public void LoadDOForSearch(String NoDO)
        {
            //if (String.IsNullOrEmpty(NoDO))
            //{
            //    client.GetAllDeliveryOrderByCostCenterCompleted += new EventHandler<GetAllDeliveryOrderByCostCenterCompletedEventArgs>(client_GetAllDeliveryOrderByCostCenterCompleted);
            //    client.GetAllDeliveryOrderByCostCenterAsync(DeliveryOrder.CostCenter); 
            //}else
            //{
                client.GetDeliveryOrderListCompleted += new EventHandler<GetDeliveryOrderListCompletedEventArgs>(client_GetDeliveryOrderListCompleted);
                client.GetDeliveryOrderListAsync(NoDO);
            //}
           
        }

        void client_GetDeliveryOrderListCompleted(object sender, GetDeliveryOrderListCompletedEventArgs e)
        {
            client.GetDeliveryOrderListCompleted -= new EventHandler<GetDeliveryOrderListCompletedEventArgs>(client_GetDeliveryOrderListCompleted);
            DeliveryOrders = new PagedCollectionView(e.Result.Where(x=>x.CostCenter.CostCenterId == DeliveryOrder.CostCenter.CostCenterId));
            gridDOVisibility = Visibility.Visible;
        }

        //void client_GetAllDeliveryOrderByCostCenterCompleted(object sender, GetAllDeliveryOrderByCostCenterCompletedEventArgs e)
        //{
        //    client.GetAllDeliveryOrderByCostCenterCompleted -= new EventHandler<GetAllDeliveryOrderByCostCenterCompletedEventArgs>(client_GetAllDeliveryOrderByCostCenterCompleted);
        //    DeliveryOrders = new PagedCollectionView(e.Result);
        //    gridDOVisibility = Visibility.Visible;
        //}


        public void LoadDOfromDO(DeliveryOrderDTO deliveryOrder)
        {
            DeliveryOrder.DeliveryOrderDetails = deliveryOrder.DeliveryOrderDetails;
        }
    }


    public class DeliveryOrderWrapViewModel : ViewModelBase
    {
        private readonly InventoryServiceClient InventoryClient;
        private readonly WarehouseServicesClient WarehouseClient;
        private readonly DeliveryOrderServicesClient client;
        private DeliveryOrderDetailDTO _DeliveryOrderDetail;
        private ObservableCollection<InventoryDTO> _Inventorys;
        private ObservableCollection<WarehouseDTO> _warehouses;


        public DeliveryOrderWrapViewModel()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                EditCommand = new DelegateCommand(Edit, CanEditCommand);
                DeleteCommand = new DelegateCommand(Delete, CanDeleteCommand);
                client = new DeliveryOrderServicesClient();
                InventoryClient = new InventoryServiceClient();
                WarehouseClient = new WarehouseServicesClient();

                AddDetailCommand = new DelegateCommand(AddDeliveryOrderDetail, CanAddDetailCommand);
                DeleteDetailCommand = new DelegateCommand(DeleteDeliveryOrderDetail, CanDeleteDetailCommand);
                GetInventoryCommand = new DelegateCommand(GetInventory, CanGetInventoryCommand);
                GetQtyUnitCommand = new DelegateCommand(GetQtyUnit, CanGetQtyUnit);
                if (DeliveryOrderViewModel.mode == Mode.Edit || DeliveryOrderViewModel.mode == Mode.Add)
                {
                    //GetWarehouseList();
                }
            }
        }

        public DeliveryOrderViewModel DeliveryOrderViewModel { get; set; }


        public ICommand EditCommand { get; set; }
        public ICommand DeleteCommand { get; set; }
        public ICommand AddDetailCommand { get; set; }
        public ICommand DeleteDetailCommand { get; set; }


        public ObservableCollection<InventoryDTO> Inventorys
        {
            get { return _Inventorys; }
            private set
            {
                if (Inventorys == value) return;
                _Inventorys = value;
                FirePropertyChanged("Inventorys");
            }
        }


        public DeliveryOrderDetailDTO DeliveryOrderDetail
        {
            get { return _DeliveryOrderDetail; }
            private set
            {
                if (DeliveryOrderDetail == value) return;
                _DeliveryOrderDetail = value;
                FirePropertyChanged("DeliveryOrderDetail");
            }
        }

        public ObservableCollection<WarehouseDTO> Warehouses
        {
            get { return _warehouses; }
            set
            {
                if (Warehouses == value) return;
                _warehouses = value;
                FirePropertyChanged("Warehouses");
            }
        }

        public ICommand GetInventoryCommand { get; set; }
        public ICommand GetQtyUnitCommand { get; set; }

        public bool CanEditCommand(Object param)
        {
            return true;
        }

        public bool CanDeleteCommand(Object param)
        {
            return true;
        }

        public bool CanAddDetailCommand(Object param)
        {
            return true;
        }

        public bool CanDeleteDetailCommand(Object param)
        {
            return true;
        }


        private void LoadWarehouses(ObservableCollection<WarehouseDTO> warehouses)
        {
            Warehouses = warehouses;
            EventAggregator.PublishMessage("LoadWarehouseToUI", warehouses);
        }

        public void Edit(Object param)
        {
            DeliveryOrderViewModel.mode = Mode.Edit;
            Navigation.MyNavigation.Navigate(new Uri("/DeliveryOrder/frmAdd", UriKind.Relative));
            Navigation.Args = param;
        }

        public void Delete(Object param)
        {
            DeleteConfirmation deleteConfirmation = new DeleteConfirmation();
            deleteConfirmation.Show();
            EventAggregator.RegisterMessage("ApprovalSucceeded", (x) =>
            {
                deleteConfirmation.Close();
                client.DeleteCompleted += client_DeleteCompleted;
                client.DeleteAsync((DeliveryOrderDTO)param);
            });
        }

        private void client_DeleteCompleted(object sender, AsyncCompletedEventArgs e)
        {
            client.DeleteCompleted -= client_DeleteCompleted;
            MessageBox.Show("Delete Success!");
            DeliveryOrderViewModel.mode = Mode.Idle;
            var VM = new DeliveryOrderViewModel();
        }


        public void GetInventoryList()
        {
            InventoryClient.GetInventoryByCriteriaCompleted +=
                InventoryClient_GetListByCriteriaCompleted;
            InventoryClient.GetInventoryByCriteriaAsync(new Dictionary<string, object>(), null, 1);
        }

        private void InventoryClient_GetListByCriteriaCompleted(object sender,
                                                                GetInventoryByCriteriaCompletedEventArgs e)
        {
            Inventorys = e.Result;
            if (DeliveryOrderViewModel.DeliveryOrder != null)
            {
                foreach (
                    DeliveryOrderDetailDTO DeliveryOrderDetail in
                        DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails)
                {
                    if (DeliveryOrderDetail.Inventory == null) continue;
                    DeliveryOrderDetail.Inventory =
                        Inventorys.FirstOrDefault(s => s.SerialNumber == DeliveryOrderDetail.Inventory.SerialNumber);
                }
            }
        }


        public void GetInventory(Object param)
        {
            if (DeliveryOrderViewModel.DeliveryOrder.Warehouse == null)
            {
                MessageBox.Show("Warehouse belum dipilih!");
                return;
            }

            DeliveryOrderDetail = (DeliveryOrderDetailDTO) param;
            if (DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Any(x=>x.Inventory.SerialNumber.ToUpper() == DeliveryOrderDetail.Inventory.SerialNumber.ToUpper()))
            {
                var res = MessageBox.Show("SerialNumber sudah ada!", "Konfirmasi", MessageBoxButton.OKCancel);
                if (res == MessageBoxResult.Cancel)
                    return;
            }


            if (DeliveryOrderDetail.Inventory == null) DeliveryOrderDetail.Inventory = new InventoryDTO();
            string SerialNumber = DeliveryOrderDetail.Inventory.SerialNumber;
            InventoryClient.GetInventoryCompleted +=
                InventoryClient_GetInventoryCompleted;
            InventoryClient.GetInventoryAsync(SerialNumber,DeliveryOrderDetail);
        }

        public void GetInventory2(Object param, WarehouseDTO warehouseSelected)
        {
            if (DeliveryOrderViewModel.DeliveryOrder.Warehouse == null)
            {
                MessageBox.Show("Warehouse belum dipilih!");
                return;
            }

            if (DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Any(x => x.Inventory.SerialNumber.ToUpper() == param.ToString().ToUpper()))
            {
                var res =  MessageBox.Show("SerialNumber sudah ada!","Konfirmasi",MessageBoxButton.OKCancel);
                if (res == MessageBoxResult.Cancel)
                        return;
            }

            InventoryClient.GetInventoryCompleted +=
                InventoryClient_GetInventoryCompleted2;
            InventoryClient.GetInventoryAsync(param.ToString(), warehouseSelected);
        }

        private void InventoryClient_GetInventoryCompleted(object sender, GetInventoryCompletedEventArgs e)
        {
            InventoryClient.GetInventoryCompleted -=
                InventoryClient_GetInventoryCompleted;
            InventoryDTO InventoryTemp = e.Result;

            if (InventoryTemp == null || string.IsNullOrEmpty(InventoryTemp.SerialNumber))
            {
                //MessageBox.Show("Barang tidak ditemukan, coba entry secara manual");
                return;
            }
           
                DeliveryOrderDetail = e.UserState as DeliveryOrderDetailDTO;
                if (DeliveryOrderDetail != null)
                {
                    if (e.UserState.GetType()==typeof(WarehouseDTO))
                        InventoryTemp.GetQtyOnHand((e.UserState as WarehouseDTO).KodeWarehouse);
                    DeliveryOrderDetail.Inventory = InventoryTemp;
                    DeliveryOrderDetail.QtyPack = InventoryTemp.QtyPack;
                    DeliveryOrderDetail.Panjang = InventoryTemp.Panjang;
                    DeliveryOrderDetail.Lebar = InventoryTemp.Lebar;
                    DeliveryOrderDetail.Panjang = InventoryTemp.Panjang;
                    DeliveryOrderDetail.Lebar = InventoryTemp.Lebar;
                    DeliveryOrderDetail.Tinggi = InventoryTemp.Warehouses.FirstOrDefault(x=>x.KodeWarehouse == DeliveryOrderViewModel.DeliveryOrder.Warehouse.KodeWarehouse).Sheet;
                    DeliveryOrderDetail.QtyUnit = InventoryTemp.Warehouses.FirstOrDefault(x => x.KodeWarehouse == DeliveryOrderViewModel.DeliveryOrder.Warehouse.KodeWarehouse).Qty;

                }
                Warehouses = new ObservableCollection<WarehouseDTO>();
                    Warehouses.Add(e.UserState as WarehouseDTO);
                    DeliveryOrderDetail.Warehouses = Warehouses;
                    DeliveryOrderDetail.Inventory.Item =
                        e.Result.Item;
                    DeliveryOrderDetail.Inventory.SatuanUnit =
                        e.Result.SatuanUnit;

            DeliveryOrderDetail.QtyUnit = DeliveryOrderDetail.Inventory.Item.IsRounded
                                              ? DeliveryOrderDetail.QtyUnit.Round(2, MidpointRounding.AwayFromZero)
                                              : DeliveryOrderDetail.QtyUnit.Round(4, MidpointRounding.AwayFromZero);
            
        }


        private void InventoryClient_GetInventoryCompleted2(object sender, GetInventoryCompletedEventArgs e)
        {
            InventoryClient.GetInventoryCompleted -=
                InventoryClient_GetInventoryCompleted2;
            InventoryDTO InventoryTemp = e.Result;

            if (InventoryTemp == null || string.IsNullOrEmpty(InventoryTemp.SerialNumber))
            {
                MessageBox.Show("Barang tidak ditemukan, coba entry secara manual");
                return;
            }

            DeliveryOrderDetail = new DeliveryOrderDetailDTO();
            DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Add(DeliveryOrderDetail);
            if (e.UserState != null) 
                InventoryTemp.GetQtyOnHand((e.UserState as WarehouseDTO).KodeWarehouse);
            DeliveryOrderDetail.Inventory = InventoryTemp;
            DeliveryOrderDetail.QtyPack = InventoryTemp.QtyPack;
            DeliveryOrderDetail.Panjang = InventoryTemp.Panjang;
            DeliveryOrderDetail.Lebar = InventoryTemp.Lebar;
            DeliveryOrderDetail.Tinggi = InventoryTemp.Warehouses.FirstOrDefault(x=>x.KodeWarehouse == DeliveryOrderViewModel.DeliveryOrder.Warehouse.KodeWarehouse).Sheet;
            DeliveryOrderDetail.QtyUnit = InventoryTemp.Warehouses.FirstOrDefault(x => x.KodeWarehouse == DeliveryOrderViewModel.DeliveryOrder.Warehouse.KodeWarehouse).Qty;
            Warehouses = new ObservableCollection<WarehouseDTO>();
            Warehouses.Add(e.UserState as WarehouseDTO);
            DeliveryOrderDetail.Warehouses = Warehouses;
            DeliveryOrderDetail.Inventory.Item =
                e.Result.Item;
            DeliveryOrderDetail.Inventory.SatuanUnit =
                e.Result.SatuanUnit;


            DeliveryOrderDetail.QtyUnit = DeliveryOrderDetail.Inventory.Item.IsRounded
                                 ? DeliveryOrderDetail.QtyUnit.Round(2,MidpointRounding.AwayFromZero)
                                 : DeliveryOrderDetail.QtyUnit.Round(4,MidpointRounding.AwayFromZero);

        }

        public void AddDeliveryOrderDetail(Object param)
        {
            DeliveryOrderDetail = new DeliveryOrderDetailDTO();
            DeliveryOrderDetail.Inventory = new InventoryDTO();
            DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Add(DeliveryOrderDetail);
        }

        public void DeleteDeliveryOrderDetail(Object param)
        {
            var DeliveryOrderDetail = (DeliveryOrderDetailDTO) param;
            if (DeliveryOrderDetail == null)
            {
                if (DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Count > 1)
                {
                    int count = DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Count;
                    DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Remove(DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails[count-1]);
                }
            }
            else
            {
                if (DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Count > 1)
                    DeliveryOrderViewModel.DeliveryOrder.DeliveryOrderDetails.Remove(DeliveryOrderDetail);
            }
        }


        public bool CanGetInventoryCommand(Object param)
        {
            return true;
        }

        public bool CanGetQtyUnit(Object param)
        {
            return true;
        }

        public void GetQtyUnit(Object param)
        {
            DeliveryOrderDetail = param as DeliveryOrderDetailDTO;
            if (DeliveryOrderDetail.Inventory != null)
                if (DeliveryOrderDetail.Inventory.SatuanUnit != null)
                {
                    DeliveryOrderDetail.QtyUnit = (DeliveryOrderDetail.Panjang *
                                                  DeliveryOrderDetail.Lebar *
                                                  DeliveryOrderDetail.Tinggi) /
                                                 DeliveryOrderDetail.Inventory.SatuanUnit.Pengali;

                    DeliveryOrderDetail.QtyUnit = DeliveryOrderDetail.Inventory.Item.IsRounded
                                         ? DeliveryOrderDetail.QtyUnit.Round(2,MidpointRounding.AwayFromZero)
                                         : DeliveryOrderDetail.QtyUnit.Round(4, MidpointRounding.AwayFromZero);
                }
                   

            
        }

        public void GetWarehouseList()
        {
            WarehouseClient.GetAllWarehouseCompleted += WarehouseClient_GetAllWarehouseCompleted;
            WarehouseClient.GetAllWarehouseAsync();
        }

        private void WarehouseClient_GetAllWarehouseCompleted(object sender, GetAllWarehouseCompletedEventArgs e)
        {
            WarehouseClient.GetAllWarehouseCompleted -= WarehouseClient_GetAllWarehouseCompleted;
            Warehouses = e.Result;
        }
    }


    public class DeliveryOrderConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                return ((dynamic) value).DONo;
            }
            else
            {
                return string.Empty;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}